#incldue "Connection.h"
#include "NetworkSystem.h"
#include "Config.h"

NetworkSystem::NetworkSystem()
{
	ListenSocket = NULL;
}

NetworkSystem::~NetworkSystem()
{
	CloseAllConnections();
}

void NetworkSystem::OnAccept(Connection* conn, const boost::system::error_code& err)
{
	if (Status != STATUS_RUNNING) // don't accept new connections if were not running
	{
		return;
	}
	Connections.push_back(conn);
	conn->OnAccept();
	Accept();
}

void NetworkSystem::Accept()
{
	if (Status != STATUS_RUNNING || !ListenSocket)
	{
		return;
	}
	Connection* conn = new Connection(IOService);
	ListenSocket->async_accept(conn->Socket, boost::bind(&NetworkSystem::OnAccept, this, conn, boost::asio::placeholders::error));
}

void NetworkSystem::Init() // pull host and port info from config
{
	std::string host, port;
	host = conf.GetValue("network.listen.host", "localhost");
	port = conf.GetValue("network.listen.port", "4096");
	ListenHost = host;
	sscanf(port.c_str(), "%d", &ListenPort);
}

void NetworkSystem::Run() // create acceptor and start the io_service
{
	ListenSocket = new boost::asio::ip::tcp::acceptor(IOService, boost::asio::ip::tcp::endpoint(boost::asio::ip::address(boost::asio::ip::address_v4(ListenHost)), ListenPort));
	Accept();
	IOService.run();
	CloseAllConnections();
	delete ListenSocket;
	ListenSocket = NULL;
}

void NetworkSystem::Stop()
{
	IOService.stop();
}

int NetworkSystem::GetStatus()
{
	return Status;
}

void NetworkSystem::Close(Connection*)
{
	std::list<Connection*>::iterator it = Connections.begin();
	if (it != Connections.end())
	{
		Connections.erase(it);
	}
}

void NetworkSystem::CloseAllConnections()
{
	std::list<Connection*>::iterator it = Connections.begin();
	while ((it = Connections.begin()) != Connections.end()) // it updates on every loop start
	{
		Connections.erase(it);
	}
}
